/**
 * 
 */
package japavo.tools.vocabulary;

import japavo.tools.vocabulary.Vocabulary.ShownWord;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *	A class representing a single book of vocabularies
 */
@XmlRootElement
public class VocabularyBook {
	/**********************************************************************************************
	 ************************************ DECLARATIONS ******************************************** 
	 *********************************************************************************************/
	/**
	 * The name of the book
	 */
	private @XmlElement String name;
	/**
	 * The language the vocabularies have
	 */
	private @XmlElement String language;
	
	/**
	 * The list of all present vocabularies in the book
	 */
	@XmlElementWrapper
	@XmlElement (name = "vocabulary")
	private List<Vocabulary> vocabularies;
	
	/**
	 * All vocabularies shuffled
	 */
	@XmlTransient
	private Vocabulary[] shuffledVocabularies;
	
	/**********************************************************************************************
	 ********************************** ENUMS AND CLASSES ***************************************** 
	 *********************************************************************************************/
	/**
	 * A record class containing a vocabulary and the information which name of it is shown
	 */
	public class ShownVocabulary {
		public Vocabulary vocabulary;
		public ShownWord shownAs;
		
		public ShownVocabulary(Vocabulary vocabulary, ShownWord shownAs) {
			this.vocabulary = vocabulary;
			this.shownAs = shownAs;
		}
	}
	
	/**********************************************************************************************
	 ************************************ CONSTRUCTORS ********************************************
	 *********************************************************************************************/
	/**
	 * Create a new book with an empty list of vocabularies
	 */
	public VocabularyBook() {
		vocabularies = new ArrayList<Vocabulary>();
	}
	
	/**********************************************************************************************
	 ************************************** FUNCTIONS ********************************************* 
	 *********************************************************************************************/
	/**
	 * Adds a new vocabulary to the book
	 */
	public void addVocabulary(Vocabulary vocabulary) {
		vocabularies.add(vocabulary);
	}
	
	public void removeVocabulary(int index) {
		vocabularies.remove(index);
	}
	
	/**
	 * Shuffles all vocabularies present in the book
	 */
	public void shuffleVocabularies() {
		shuffledVocabularies = new Vocabulary[vocabularies.size()];
		int randomIndex = (int) (Math.random() * vocabularies.size());
		
		for (int i = 0; i < vocabularies.size(); i++) {
			while (shuffledVocabularies[randomIndex] != null) {
				randomIndex = (int) (Math.random() * vocabularies.size());	
			}
			shuffledVocabularies[randomIndex] = vocabularies.get(i);
		}
	}
	
	/**
	 * The vocabulary was played, so increase it's stats
	 * 
	 * @param index
	 *            the vocabulary played
	 * @param correct
	 *            indicates whether it was correct or not
	 */
	public void vocabularyPlayed(int index, boolean correct) {
		// out of bounds
		if (index >= vocabularyCount())
			return;
		
		// increase stats
		Vocabulary vocabulary = shuffledVocabularies[index];
		vocabulary.increasePlayed();
		if (correct) vocabulary.increaseCorrect();
	}
	
	/**********************************************************************************************
	 ********************************** GETTER AND SETTER ***************************************** 
	 *********************************************************************************************/
	public Vocabulary getVocabulary(int index) {
		if (index >= vocabularyCount())
			return null;
		return getVocabularies().get(index);
	}
	
	public List<Vocabulary> getVocabularies() {
		return vocabularies = (vocabularies == null ? new ArrayList<Vocabulary>() : vocabularies); 
	}
	
	public int vocabularyCount() {
		return getVocabularies().size();
	}
	
	public ShownVocabulary getVocabularyToShow(int index) {
		// out of range
		if (index >= vocabularies.size())
			return null;
		
		// TODO make variable
		ShownWord shownAs = Math.random() <= Double.parseDouble(System.getProperty("FOREIGN_PROBABILITY"))
							? ShownWord.FOREIGN : ShownWord.MOTHER_TONGUE;
		
		return new ShownVocabulary(shuffledVocabularies[index], shownAs);
	}
	
	@XmlTransient
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}

	@XmlTransient
	public String getLanguage() {
		return language;
	}	
	
	public void setLanguage(String language) {
		this.language = language;
	}
	
}
